package com.moss.cloud.common.file.realize;

import com.moss.cloud.common.file.exception.StorageErrorType;
import com.moss.cloud.common.file.model.StorageModel;
import com.moss.cloud.common.file.model.UploadRes;
import com.moss.cloud.common.file.operation.FileStorageOperation;
import com.moss.cloud.common.file.utils.*;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.region.Region;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.ByteArrayInputStream;

/**
 * 腾讯云存储实现
 *
 * @author 瑾年
 * @date 2023年4月19日
 */
@Slf4j
public class TencentStorage implements FileStorageOperation {
    /**
     * 上传文件
     *
     * @param storageModel
     * @return
     */
    @Override
    @SneakyThrows
    public UploadRes upload(StorageModel storageModel) {
        String fileName = storageModel.getIsBase64() ? storageModel.getName() : storageModel.getMultipartFile().getOriginalFilename();
        FileDataPreUtil.isSizeAllowed(storageModel);
        FileDataPreUtil.isAllowed(fileName, storageModel.getStorageConfig().getSuffix());
        COSClient cosClient = this.cosClient(storageModel);
        String bucketName = storageModel.getStorageConfig().getBucket() + "-" + storageModel.getStorageConfig().getAppId();
        String path;
        String renameFileName = UUIDUtil.rename(fileName);
        if(storageModel.getInputStream() == null){
            if (storageModel.getIsBase64()) {
                byte[] bytes = FileDataPreUtil.base64ToBytes(storageModel.getImgBase64());
                path = TencentUtil.tencentUpload(new ByteArrayInputStream(bytes), cosClient, bucketName, renameFileName,storageModel.getStorageConfig().getRegion());
            } else {
                path = TencentUtil.tencentUpload(storageModel.getMultipartFile().getInputStream(), cosClient, bucketName, renameFileName,storageModel.getStorageConfig().getRegion());
            }
        }else {
            path = TencentUtil.tencentUpload(storageModel.getInputStream(), cosClient, bucketName, renameFileName,storageModel.getStorageConfig().getRegion());
        }
        return UploadResUtil.createUploadRes(path, fileName, storageModel.getStorageConfig().getType());
    }

    /**
     * 删除文件
     *
     * @param storageModel
     */
    @Override
    public void removeFile(StorageModel storageModel) {
        String bucketName = storageModel.getStorageConfig().getBucket() + "-" + storageModel.getStorageConfig().getAppId();
        COSClient cosClient = this.cosClient(storageModel);
        TencentUtil.delObject(cosClient, storageModel.getFileId(), bucketName);
    }

    /**
     * 生成腾讯云客户端
     *
     * @param storageModel
     * @return
     */
    private COSClient cosClient(StorageModel storageModel) {
        BooleanHandel.trueThrow(StringUtils.isBlank(storageModel.getStorageConfig().getAccessKey())).throwMessage(StorageErrorType.ACCESS_KEY_EMPTY);
        BooleanHandel.trueThrow(StringUtils.isBlank(storageModel.getStorageConfig().getSecretKey())).throwMessage(StorageErrorType.SECRET_KEY_EMPTY);
        BooleanHandel.trueThrow(StringUtils.isBlank(storageModel.getStorageConfig().getRegion())).throwMessage(StorageErrorType.REGION_EMPTY);
        BooleanHandel.trueThrow(StringUtils.isBlank(storageModel.getStorageConfig().getAppId())).throwMessage(StorageErrorType.APPID_EMPTY);
        // 1 初始化用户身份信息(secretId, secretKey)
        COSCredentials cred = new BasicCOSCredentials(storageModel.getStorageConfig().getAccessKey(), storageModel.getStorageConfig().getSecretKey());
        // 2 设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
        // clientConfig中包含了设置region, https(默认http), 超时, 代理等set方法, 使用可参见源码或者接口文档FAQ中说明
        ClientConfig clientConfig = new ClientConfig(new Region(storageModel.getStorageConfig().getRegion()));
        // 3 生成cos客户端
        COSClient cosClient = new COSClient(cred, clientConfig);
        return cosClient;
    }
}
